package day17.code.day17.src.cn.tedu.api;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

//利用反射new/set/get/invoke
public class Test3_Student {
    public static void main(String[] args) throws Exception {
        method();//创建对象
      //  method2();//执行方法
      //  method3();//操作属性
    }

    //3.操作属性--getField()-set()/get()
    public static void method3() throws Exception {
        //1,获取Class对象
        Class c = Student.class;
        //2,获取指定的属性--参数是成员变量的名称
        Field f = c.getField("age");
        System.out.println(f.getName());//获取属性名
        System.out.println(f.getType().getName());//获取属性类型

        //3,设置属性的值set(1,2)--1是反射的new的对象,2是要给属性设置的具体值
        Object obj = c.newInstance();
        f.set(obj,20);
        //4,获取属性的值并打印
        System.out.println(obj);
    }

    //2.执行方法--getMethod() -newInstance()
    public static void method2() throws Exception {
        //1,获取Class对象
        Class c = Student.class;

        //2,获取指定的方法--参数是方法名称
        //2.1--获取不带参的方法-- show()
        Method a = c.getMethod("show");
        //2.2--获取带参的方法-- test(int a)
        Method m = c.getMethod("test", int.class);

        //3.利用反射创建对象
        Object obj = c.newInstance();

        //4,执行方法invoke(1,2)--1是对象,2是方法要传入的具体参数
        a.invoke(obj); //不带参

        m.invoke(obj,34); //带参
    }

    //1.利用反射创建对象--newInstance()
    public static void method() throws Exception {
        //1,获取Class对象
        Class c = Student.class;
        //自己new    Student s = new Student();
        //2,利用反射new
        //Class对象只能触发无参构造方法
        Object o = c.newInstance();
        //Student{name='null', age=0}
        System.out.println(o);

        //TODO 触发含参构造
        //获取指定的含参构造方法,并要写入含参构造中的参数类型的Class对像
        Constructor con = c.getConstructor(String.class);
        //触发含参构造--反射创建对像时，要传入的参数
        Object obj = con.newInstance("jack");
        System.out.println(obj);

        //获取对象实例中的成员变量的值
        Field f = c.getField("name");
        System.out.println(f.get(obj));
    }
}
